/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

//#include <向量.h>
#include <basic_vec.h>
#include <stdio.h>
#include <文件/file_载入保存数据.h>

typedef struct _S_ListItem {
	void*		ptr_userData;
	_S_ListItem*	ptr_头;
	_S_ListItem*	ptr_尾;
}S_ListItem;

typedef struct _S_List {
	S_ListItem* ptr_item;
	uint32      count;
}S_List;


typedef struct {
	void*	ptr_userData;
	S_List*	prt_tree;
}S_Tree;

typedef void(*fn_list_data)(void* data);
typedef bool(*fn_list_sort)(void* d1, void* d2);

S_List* f_core_createList();
void	f_core_releaseList(S_List* list);
void    f_core_list_clear(S_List* list);

void	f_core_list_free_data(S_List* list, fn_list_data func);
void	f_core_list_sort(S_List* list, fn_list_sort func);
void	f_core_list_foreach(S_List* list, fn_list_data func);


S_List* f_core_copyList(S_List* 源);
S_ListItem* f_core_list_last(S_ListItem* list);
S_ListItem* f_core_list_nth(S_ListItem* list, int64 pos);
//S_List* f_core_list_offset(S_List* list, int32 offset);
uint64	f_core_list_size(S_List* list);


S_List*	f_core_addListEndItem(S_List* list, void* data = nullptr);
void	f_core_remListItem(S_List* list);
void	f_core_list_erase(S_List* list, S_ListItem* item, fn_list_data func);


S_ListItem* f_core_getItem(S_List* list, uint64 id);
void        f_core_list_moveItem(S_List* list, uint64 loc, uint64 d);

void	f_core_list_swap(S_List* list_s, S_List* list_e);
void	f_core_list_swapItem(S_ListItem* list_s, S_ListItem* list_e);



S_Tree* f_core_createTree(void* data);
void	f_core_releaseTree(S_Tree* tree);


void	f_core_TreeSetItem(S_Tree* tree, void* data);
void	f_core_TreeAddItem(S_Tree* tree, S_Tree* lefTree);
bool	f_core_TreeRemoveItem(S_Tree* tree, S_Tree* leaf);





#define DEF_FOR_LIST(it, ob) for (auto (it) = (ob); (it); (it) = (it)->ptr_尾)
#define DEF_FOR_LIST_反向(it, ob) for (auto (it) = (ob); (it); (it) = (it)->ptr_头)

//#define DEF_FOREACH_LIST(it, i, ob) for (auto (it) = (ob); (it); (it) = (it)->prt_尾)


#define _S_Array			\
typedef struct {			\
	uint8*	ptr_userData;	\
	uint32	count;			\
}S_Array;

_S_Array;


#define _S_1DArray          \
typedef struct {            \
	S_Array** ptr_userData; \
	uint32	count;		    \
}S_1DArray;

_S_1DArray;






typedef bool(*fn_array_sort)(uint8* d1, uint8* d2);
typedef void(*fn_array_free)(S_Array* array);

S_Array* f_core_array_new(uint64 num, uint32 elt_size, bool 多维 = false);
S_Array* f_core_array_new_type(uint64 num, E_值类型 类型);
void f_core_array_free(S_Array* array);
void f_core_array_resize(S_Array* array, uint64 num);
void f_core_array_reserve(S_Array* array, uint64 num);

void f_core_array_push_back(S_Array* array, const uint8* data);
void f_core_array_push_back_block(S_Array* array, const uint8* data, uint64 字节数, uint32 元素大小 = 1);

void f_core_array_pop_back(S_Array* array);
void f_core_array_pop_front(S_Array* array);
void f_core_array_insert_elt(S_Array* array, uint64 index, const uint8* data);
bool f_core_array_erase(S_Array* array, uint32 loc, uint32 num = 1);
void f_core_array_clear(S_Array* array);
void f_core_array_sort(S_Array* array, fn_array_sort sort_fn);
void f_core_array_change_elt_size(S_Array* array, const uint32 size);
uint8* f_core_array_at(S_Array* array, uint32 offset);
uint8* f_core_array_back(S_Array* array);
//void* f_core_array_at_a(S_Array* array, uint32 offset);
uint32 f_core_array_get_elt_size(const S_Array* src);

S_Array* f_core_array_from(const S_Array* src);
void f_core_array_copy(S_Array* dst, const S_Array* src);
void f_core_array_assign(S_Array* dst, const S_Array* src);
void f_core_array_append(S_Array* dst, const S_Array* src);
S_Array* f_core_array_merge(const S_Array* m0, const S_Array* m1);
void f_core_array_insert(S_Array* dst, const S_Array* src, uint64 offset = -1);
int32 f_core_array_find(S_Array* array, const uint8* data);
S_Array* f_core_array_shuffle(S_Array* a, const S_iVec2Array* index, bool copy = false);
S_I32Array* f_core_array_random_shuffel(uint32 num, int32 种子);
uint32 f_core_array_statistics(S_Array* a, uint8* 元素);
void f_core_array_swap(S_Array* a, uint32 s, uint32 e);
S_Array* f_core_array_extract(S_Array* a, const ivec2& 区间, uint32 num, int32 随机种子, bool copy = false);

E_值类型 f_core_array_getType(S_Array* a);
void f_core_array_不对等复制(S_Array* a, const S_Array* b);
void f_core_array_元素复制(S_Array* a, const S_Array* b, uint32 la, uint32 lb);
void f_core_array_区间自拷贝(S_Array* a, S_UI32Array* indexs, uint32 offset);


void f_core_array_save(S_Array* array, FILE* f);
void f_core_array_load(S_Array* array, FILE* f);

void f_core_array_包(S_Array* array, S_UI8Array* 块);
const uint8* f_core_array_解(S_Array* array, const uint8* 块);


#define f_array_back(type, array) *(type*)f_core_array_back((S_Array*)array);
#define f_array_at(type, array, id) *(type*)f_core_array_at((S_Array*)array, id);




S_iVec2Array* f_core_index_sort(S_I32Array* 块, bool 降序);





